package com.boil.qz.safekavass.service;

import com.alibaba.fastjson.JSONObject;
import com.boil.pojo.ResultVo;
import com.boil.qz.safekavass.model.WeixinUser;
import com.boil.qz.safekavass.repository.WeixinUserRepository;
import com.boil.qz.safekavass.weixin.WeixinException.WeixinException;
import com.boil.qz.safekavass.weixin.request.param.BindPhoneParam;
import com.boil.qz.safekavass.weixin.util.WeixinUtils;
import com.boil.util.Constants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by ChenYong on 2017-05-22.
 * <br>
 * 微信用户 Service。
 */
@Service
public class WeixinUserService extends JpaRepositoryService<WeixinUser, Long> {
    /**
     * 注入微信用户实体仓库
     */
    @Autowired
    private WeixinUserRepository weixinUserRepository;

    /**
     * 处理绑定手机号的业务。
     *
     * @param resultVo 结果映射实例
     * @param param    绑定手机号的请求参数
     */
    public void doBindPhone(ResultVo resultVo, BindPhoneParam param) {
        // 查询手机号是否已被绑定
        WeixinUser weixinUser1 = weixinUserRepository.findByPhone(param.getPhone());

        // 手机号未被绑定
        if (weixinUser1 == null) {
            // 根据 openid 获取微信用户
            WeixinUser weixinUser2 = weixinUserRepository.findByOpenid(param.getOpenid());
            weixinUser2.setPhone(param.getPhone());

            resultVo.setResultMsg(String.format("恭喜您，绑定手机号【%s】成功！", param.getPhone()));

            // 手机号已被绑定
        } else {
            resultVo.setResultCode(Constants.ERROR);
            resultVo.setResultMsg(String.format("抱歉，绑定手机号失败，原因：手机号【%s】已被别人绑定！", param.getPhone()));
        }
    }

    /**
     * 处理同步微信用户信息的业务。
     */
    public void doSyncWeixinUserInfo() {
        try {
            // 从头开始拉取 openid
            JSONObject openidJSONObject = WeixinUtils.sendHttpsGet(String.format(WeixinUtils.URL_GET_USER_LIST, WeixinUtils.ACCESS_TOKEN, Constants.EMPTY_STR));

            // 获取成功
            if (StringUtils.isBlank(openidJSONObject.getString(WeixinUtils.ERRCODE_STR))) {
                // openid 的总列表
                List<String> data = new ArrayList<String>();
                // 关注该公众账号的总用户数
                int total = openidJSONObject.getIntValue(WeixinUtils.TOTAL_STR);
                // 拉取列表的最后一个用户的 openid
                String nextOpenid = openidJSONObject.getString(WeixinUtils.NEXT_OPENID_STR);

                data.addAll(openidJSONObject.getJSONObject(WeixinUtils.DATA_STR).getJSONArray(WeixinUtils.OPENID_STR).toJavaList(String.class));

                // 判读是否分页拉取
                if (total > Constants.VALUE_10000) {
                    // 总页数
                    int pages = Constants.VALUE_0;

                    // 整除
                    if ((total % Constants.VALUE_10000) == Constants.VALUE_0) {
                        pages = (total / Constants.VALUE_10000);

                        // 非整除
                    } else {
                        pages = ((total / Constants.VALUE_10000) + Constants.VALUE_1);
                    }

                    // 排除第一页
                    pages--;

                    // 分页拉取
                    for (int i = Constants.VALUE_0; i < pages; i++) {
                        // 从 next_openid 开始拉取 openid
                        openidJSONObject = WeixinUtils.sendHttpsGet(String.format(WeixinUtils.URL_GET_USER_LIST, WeixinUtils.ACCESS_TOKEN, nextOpenid));

                        // 获取成功
                        if (StringUtils.isBlank(openidJSONObject.getString(WeixinUtils.ERRCODE_STR))) {
                            nextOpenid = openidJSONObject.getString(WeixinUtils.NEXT_OPENID_STR);

                            data.addAll(openidJSONObject.getJSONObject(WeixinUtils.DATA_STR).getJSONArray(WeixinUtils.OPENID_STR).toJavaList(String.class));
                        }
                    }
                }

                log.info("微信用户作业（WeixinUserTask）--->拉起微信服务器上的用户数量：{}", data.size());

                // 遍历，根据 openid 获取微信服务器上的用户基本信息
                for (String openid : data) {
                    try {
                        // 根据 openid 查询微信用户
                        WeixinUser weixinUser = weixinUserRepository.findByOpenid(openid);
                        // 微信服务器上的用户基本信息
                        JSONObject weixinUserJSONObject = null;

                        try {
                            // 根据 openid 获取微信服务器上的用户基本信息
                            weixinUserJSONObject = WeixinUtils.sendHttpsGet(String.format(WeixinUtils.URL_GET_USER_INFO, WeixinUtils.ACCESS_TOKEN, openid));

                            log.info("微信用户作业（WeixinUserTask）--->openid[{}]获取微信服务器上的用户基本信息：{}", openid, weixinUserJSONObject.toJSONString());
                        } catch (Exception e) {
                            log.error("微信用户作业（WeixinUserTask）--->openid[{}]获取微信服务器上的用户基本信息时出现异常：{}", openid, e);
                        }

                        // 未关注
                        if (weixinUser == null) {
                            weixinUser = new WeixinUser();
                            weixinUser.setOpenid(openid);
                        }

                        weixinUser.setUnsubscribeTime(null);

                        // 获取成功
                        if ((weixinUserJSONObject != null) && StringUtils.isBlank(weixinUserJSONObject.getString(WeixinUtils.ERRCODE_STR))) {
                            // 获取关注状态：0-未关注；1-已关注
                            int subscribe = weixinUserJSONObject.getIntValue(WeixinUtils.SUBSCRIBE_STR);

                            weixinUser.setSubscribe(subscribe);

                            // 未关注
                            if (subscribe == Constants.VALUE_0) {
                                weixinUser.setSubscribeTime(null);

                                // 已关注
                            } else {
                                weixinUser.setNickname(weixinUserJSONObject.getString(WeixinUtils.NICKNAME_STR));
                                weixinUser.setSex(weixinUserJSONObject.getIntValue(WeixinUtils.SEX_STR));
                                weixinUser.setLanguage(weixinUserJSONObject.getString(WeixinUtils.LANGUAGE_STR));
                                weixinUser.setCity(weixinUserJSONObject.getString(WeixinUtils.CITY_STR));
                                weixinUser.setProvince(weixinUserJSONObject.getString(WeixinUtils.PROVINCE_STR));
                                weixinUser.setCountry(weixinUserJSONObject.getString(WeixinUtils.COUNTRY_STR));
                                weixinUser.setHeadimgurl(weixinUserJSONObject.getString(WeixinUtils.HEADIMGURL_STR));
                                weixinUser.setSubscribeTime(new Date(weixinUserJSONObject.getLongValue(WeixinUtils.SUBSCRIBE_TIME_STR) * 1000L));
                                weixinUser.setUnionid(weixinUserJSONObject.getString(WeixinUtils.UNIONID_STR));
                                weixinUser.setRemark(weixinUserJSONObject.getString(WeixinUtils.REMARK_STR));
                                weixinUser.setGroupid(weixinUserJSONObject.getLongValue(WeixinUtils.GROUPID_STR));
                            }
                        }

                        // 未关注
                        if (weixinUser.getId() == null) {
                            save(weixinUser);
                        }

                        // 由于有多个用户信息，所以每次都把用户信息同步到数据库中
                        flush();
                    } catch (WeixinException e) {
                        log.error("微信用户作业（WeixinUserTask）--->openid[{}]获取微信服务器上的用户基本信息时出现异常：{}", openid, e);
                    }
                }
            }
        } catch (Exception e) {
            log.error("微信用户作业（WeixinUserTask）--->同步微信服务器上的用户基本信息到本地数据库中时出现异常：{}", e);
        }
    }
}